package com.wellview.template.presenter;



import com.wellview.http.OkHttpUtils;
import com.wellview.http.builder.PostFormBuilder;
import com.wellview.http.builder.PostFormFileBuilder;
import com.wellview.http.callback.Callback;
import com.wellview.http.request.RequestCall;
import com.wellview.template.logger.Logger;
import com.wellview.template.modle.BaseBehavior;
import com.wellview.template.utils.Utils;
import com.wellview.template.utils.XulUtils;

import java.util.HashMap;

import okhttp3.Call;
import okhttp3.Response;


/**
 * Created by jizi.chen on 2017/8/28.
 */

public abstract class BaseProvider {
    public String TAG = getClass().getSimpleName();
    protected HashMap<String,String> paraMap = new HashMap<String,String>();
    protected String url;
    public BaseBehavior mBehavior;

    public BaseBehavior.Clause clause ;

    public static void init(){
        ProviderFactory.register(SplashProvider.class);
        ProviderFactory.register(LoginProvider.class);
        ProviderFactory.register(JSProvider.class);
    }

    public BaseProvider() {

    }

    public static OkHttpUtils getHttpClient() {
        return OkHttpUtils.getInstance();
    }

    public BaseProvider addClause(BaseBehavior.Clause clause) {
        this.clause = clause;
        return this;
    }


    public void excute(){
        RequestCall call = buildRequest();
        if (call != null){
            call.execute(new Callback<String>() {
                @Override
                public String parseNetworkResponse(Response response, int id) throws Exception {
                    Logger.i(TAG,"parseNetworkResponse>> " + response.message());
                    return null;
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    Logger.i(TAG,"onError >> " + e.getMessage());
                }

                @Override
                public void onResponse(String response, int id) {
                    Logger.i(TAG,"onResponse >> "+response);
                }
            });
        }

    }

    public void execute(final ResultListener listener){
        RequestCall call = buildRequest();
        if (call != null){
            call.execute(new Callback<String>() {
                @Override
                public String parseNetworkResponse(Response response, int id) throws Exception {
                    Logger.i(TAG,"parseNetworkResponse>> " + response.message());
//                    listener.parseNetworkResponse(response,id);
                    return response.body().string();
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    listener.onError(call,e,id);
                    Logger.e(TAG,"onError >> " + e.getMessage());
                    if (clause != null){
                        clause.clearAll();
                        Logger.i(TAG,"onError clear clause done");
                    }
                }

                @Override
                public void inProgress(float progress, long total, int id) {
                    listener.inProgress(progress,total,id);
                }
                @Override
                public void onResponse(String response, int id) {
                    Logger.i(TAG, "Thread cur thread " + Thread.currentThread().getName() + " and onResponse >> " + response);
                    listener.onResponse(response,id);
                    if (clause != null){
                        clause.clearAll();
                        Logger.i(TAG,"onResponse clear clause done");
                    }
                }
            });
        }

    }

    private RequestCall buildRequest() {
        BaseBehavior.Clause.Method method = clause.method;

        RequestCall call = null;
        switch (method){
            case GET:
                 call = OkHttpUtils.get()
                         .url(url)
                         .headers(clause.headerMap)
                         .params(clause.clauseMap)
                         .build();
                break;
            case PULL:

                if (containsFile()){
                    PostFormFileBuilder postFormFileBuilder = OkHttpUtils.postForm();
                    postFormFileBuilder.files("post_file",clause.fileMap);
                    call = postFormFileBuilder
                            .url(url)
                            .headers(clause.headerMap)
                            .params(clause.clauseMap)
                            .build();
                }else {
                    call = OkHttpUtils.post()
                            .url(url)
                            .headers(clause.headerMap)
                            .params(clause.clauseMap)
                            .build();
                }

            default:
                    break;
        }
        Logger.e(TAG, "SEND_REQUEST : request url is " + url + "\n"
                + "clause info is " + clause.toString() + "\n"
                + "timestamp " + Utils.formatUTC(System.currentTimeMillis(),"")
        );
        return call;
    }

    private boolean containsFile() {
        return "true".equals(clause.getConditionValue(BaseBehavior.Clause.CONTAINS_FILE));
    }

    public BaseProvider setUrl(String url){
        this.url = url;
        return this;
    }

    public interface ResultListener<T>{
        void onError(Call call, Exception e, int id);
        void onResponse(T response, int id);
        void inProgress(float progress, long total , int id);
    }

    public abstract class SimpleResultListener<T> implements ResultListener{
        public abstract void onError(Call call, Exception e, int id);
        public abstract void onResponse(String response, int id);
        public abstract void inProgress(float progress, long total , int id);
    }

}
